#-*-coding:UTF-8 -*-
from pymem import Pymem
import re
import tkinter as tk
from tkinter import messagebox


def validate_number(number_string):
        number_pattern=r'^[0-9]+$'
        if re.match(number_pattern,number_string):
                return True
        return False
# exe名称
##pm = Pymem('WinKawaks.exe')
try:
        pm = Pymem('WinKawaks.exe')
except Exception as e:
        print(f"发生错误:{e}")
        messagebox.showinfo("提示",f"发生错误:{e}！")
        exit()
finally:
        
        print('Process id: %s' % pm.process_id)


def Get_moduladdr(dll): #读DLL模块基址
	modules=list(pm.list_modules()) #列出exe的全部DLL模块
	for module in modules:
		if module.name== dll:
			Moduladdr=module.lpBaseOfDll
	return Moduladdr

print("寻找文件基址")
base=Get_moduladdr('WinKawaks.exe')
print(base)

##UI控件布局###############################################################################

master=tk.Tk()

master.title('游戏外挂☆★☆★☆★')  # 标题
master.geometry('500x500+300+200')  # 位置及大小

tk.Label(master,text="手雷值：" ,foreground="blue").grid(row=0)
tk.Label(master,text="血 值：",foreground="orange").grid(row=1)
tk.Label(master,text="生命值：",foreground="orange").grid(row=2)
tk.Label(master,text="时间：",foreground="pink").grid(row=3)
tk.Label(master,text="横坐标：",foreground="purple").grid(row=4)
tk.Label(master,text="纵坐标：",foreground="purple").grid(row=5)
tk.Label(master,text="敌人数量：",foreground="orange").grid(row=6)
tk.Label(master,text="生命值：",foreground="orange").grid(row=7)
tk.Label(master,text="生命值：",foreground="orange").grid(row=8)


shoulei=tk.StringVar()
xuezhi=tk.StringVar()
life=tk.StringVar()
cur_time=tk.StringVar()
posx=tk.StringVar()
posy=tk.StringVar()
enemy_count=tk.StringVar()

e1=tk.Entry(master,textvariable=shoulei)
e2=tk.Entry(master,textvariable=xuezhi)
e3=tk.Entry(master,textvariable=life)
e4=tk.Entry(master,textvariable=cur_time,foreground="pink")
e5=tk.Entry(master,textvariable=posx)
e6=tk.Entry(master,textvariable=posy)
e7=tk.Entry(master,textvariable=enemy_count)
e8=tk.Entry(master,textvariable=life)
e9=tk.Entry(master,textvariable=life)







e1.grid(row=0,column=1,padx=10,pady=5)
e2.grid(row=1,column=1,padx=10,pady=5)
e3.grid(row=2,column=1,padx=10,pady=5)
e4.grid(row=3,column=1,padx=10,pady=5)
e5.grid(row=4,column=1,padx=10,pady=5)
e6.grid(row=5,column=1,padx=10,pady=5)
e7.grid(row=6,column=1,padx=10,pady=5)
e8.grid(row=7,column=1,padx=10,pady=5)
e9.grid(row=8,column=1,padx=10,pady=5)



btn1=tk.Button(master,text="√",width=10,foreground="green")
btn1.grid(row=0,column=3,sticky="w",padx=10,pady=5)

btn2=tk.Button(master,text="√",width=10,foreground="green")
btn2.grid(row=1,column=3,sticky="w",padx=10,pady=5)

btn3=tk.Button(master,text="√",width=10,foreground="green")
btn3.grid(row=2,column=3,sticky="w",padx=10,pady=5)

btn4=tk.Button(master,text="√",width=10,foreground="pink")
btn4.grid(row=3,column=3,sticky="w",padx=10,pady=5)

btn5=tk.Button(master,text="√",width=10,foreground="purple")
btn5.grid(row=4,column=3,sticky="w",padx=10,pady=5)

btn6=tk.Button(master,text="√",width=10,foreground="purple")
btn6.grid(row=5,column=3,sticky="w",padx=10,pady=5)

btn7=tk.Button(master,text="start shooting",width=10,foreground="green")
btn7.grid(row=6,column=3,sticky="w",padx=10,pady=5)

btn8=tk.Button(master,text="√",width=10,foreground="green")
btn8.grid(row=7,column=3,sticky="w",padx=10,pady=5)

btn9=tk.Button(master,text="√",width=10,foreground="green")
btn9.grid(row=8,column=3,sticky="w",padx=10,pady=5)



strvar=tk.StringVar()
strvar.set("■")
Btn_update=tk.Button(master,textvariable=strvar,width=10,foreground="red")
Btn_update.grid(row=9,column=0,sticky="w",padx=10,pady=5)

tk.Button(master,text="×",width=10,command=master.quit).grid(row=9,column=3,sticky="e",padx=10,pady=5)	

##启动线程 自动更新数据###############################################################################

import threading
import time
 
exitFlag = 0
is_update=True

shoot=1

exe_addr=pm.read_int(base+0x2c6f00) #116bd020
 
class myThread (threading.Thread):   #继承父类threading.Thread
	def __init__(self, threadID, name):
		threading.Thread.__init__(self)
		self.threadID = threadID
		self.name = name
	def run(self):                   #把要执行的代码写到run函数里面 线程在创建后会直接运行run函数 
		print("Starting " + self.name)
		print_time(self.name, 1)
		
		print ("Exiting " + self.name)

def print_time(threadName, delay):
	while True:
		if exitFlag:
			(threading.Thread).exit()
		time.sleep(delay)
		update()
		print ("%s: %s" % (threadName, time.ctime(time.time())))
def update():
        if not is_update:
                return
        
	##获取手雷值
        sl=pm.read_uchar(p1addr+0xff5bcb) #58b43f2
	
        print("手雷")
        print(sl)

	##获取血值
        xz=pm.read_uchar(p1addr+0xff8e9e) #58b43f2
        ##获取生命值
        life.set(pm.read_uchar(p1addr+0xff5ba5))
        ##获取时间值

        shiwei=pm.read_uchar(p1addr+0xff18ae)
        gewei=pm.read_uchar(p1addr+0xff18ac)
        cur_time.set(int(shiwei/2)*10+int(gewei/2))
        shoulei.set(sl)
        xuezhi.set(xz)

        ##获取坐标
        posx.set(pm.read_short(p1addr+0xff8e88))
        posy.set(pm.read_short(p1addr+0xff8e90))
        ##显示敌人数量
        enemy_count.set(pm.read_uchar(p1addr+0xff5d97))

 
# 创建新线程
thread1 = myThread(1, "Thread-1")
#thread2 = myThread(2, "Thread-2")
 
# 开启线程
thread1.start()
#thread2.start()
 
print ("Exiting Main Thread")


##读取指针

#base =pm.get_base()
try:
        p1addr=pm.read_int(base+0x2c5320) #048be827


        ##        ##获取手雷值
        ##        sl=pm.read_uchar(p1addr+0xff5bcb) #58b43f2
        ##
        ##        ##获取血值
        ##        xz=pm.read_uchar(p1addr+0xff8e9e) #58b43f2
        ##        ##读取生命值
        ##        life.set(pm.read_uchar(p1addr+0xff5ba5))
        update()
except Exception as e:
        print(f"发生错误:{e}")
        messagebox.showinfo("提示",f"发生错误:{e}！")
        exit()
##print(le(sl))
#0x58b43f2
#sldata=pm.read_uchar(0x58b43f2)
##shoulei.set(sl)
##xuezhi.set(xz)


######################################################################################################

def changeVar():
	print("手雷值:《%s》"%shoulei.get())
	v1=shoulei.get()
	if not validate_number(v1):
		messagebox.showinfo("提示","请输入数字！")
		shoulei.set(4)
		return
	v1=int(v1)
	if v1>16:
		messagebox.showinfo("提示","不得大于16！")
		shoulei.set(4)
		return
	
		
        #return
	#pm.write_uchar(0x58b43f2, v1)
	pm.write_uchar(p1addr+0xff5bcb,v1) 
	#shoulei.set(9)
	#print("作者:《%s》"%e2.get())
	#e1.delete(0,"end")
	#e2.delete(0,"end")

def changeVar1():
	print("手雷值:《%s》"%xuezhi.get())
	v2=xuezhi.get()
	if not validate_number(v2):
		messagebox.showinfo("提示","请输入数字！")
		xuezhi.set(136)
		return
	v2=int(v2)
	if v2>136:
		messagebox.showinfo("提示","不得大于136！")
		xuezhi.set(136)
		return
	
		
        #return
	#pm.write_uchar(0x58b43f2, v1)
	pm.write_uchar(p1addr+0xff8e9e,v2)
	#shoulei.set(9)
	#print("作者:《%s》"%e2.get())
	#e1.delete(0,"end")
	#e2.delete(0,"end")
def changeVar3():
	print("生命值:《%s》"%life.get())
	v2=life.get()
	if not validate_number(v2):
		messagebox.showinfo("提示","请输入数字！")
		life.set(10)
		return
	v2=int(v2)
	if v2>10:
		messagebox.showinfo("提示","不得大于10！")
		life.set(10)
		return
	
		
        #return
	#pm.write_uchar(0x58b43f2, v1)
	pm.write_uchar(p1addr+0xff5ba5,v2)

def changeVar4():
	print("时间:《%s》"%cur_time.get())
	v2=cur_time.get()
	if not validate_number(v2):
		messagebox.showinfo("提示","请输入数字！")
		cur_time.set(99)
		return
	v2=int(v2)
	if v2>99:
		messagebox.showinfo("提示","不得大于99！")
		cur_time.set(99)
		return
	
		
        #return
	#pm.write_uchar(0x58b43f2, v1)
        ##	设置十位
	pm.write_uchar(p1addr+0xff18ae,int(v2/10)*2)
        ##设置个位
	pm.write_uchar(p1addr+0xff18ac,int(v2%10)*2)


def changeVar5():
	
	v2=posx.get()
	if not validate_number(v2):
		messagebox.showinfo("提示","请输入数字！")
		posx.set(99)
		return
	v2=int(v2)
	
		
        #return
	#pm.write_uchar(0x58b43f2, v1)
        ##设置横坐标
	pm.write_short(p1addr+0xff8e88,v2)

def changeVar6():
	
	v2=posy.get()
	if not validate_number(v2):
		messagebox.showinfo("提示","请输入数字！")
		posx.set(99)
		return
	v2=int(v2)
	
		
        #return
	#pm.write_uchar(0x58b43f2, v1)
        ##设置横坐标
	pm.write_short(p1addr+0xff8e90,v2)
      

shoot=0

  ##设置持枪射击  2C6f00
def changeVar7():
        global shoot
        if shoot == 0:
                shoot=1
                pm.write_int(exe_addr+0x268e6,0x4e714e71)
                pm.write_uchar(p1addr+0xff5d97,1)
                btn7.config(text="stop shooting",foreground="red")
        else:
                shoot=0
                pm.write_int(exe_addr+0x268e6,0xdd96422d )
                btn7.config(text="start shooting",foreground="green")  
            
        ##设置横坐 2d 42 96 dd   ->714e 714e
	
       
       
	
def cmd_mod():
	global is_update
	if is_update:
		is_update=False
		strvar.set("▲")
		Btn_update.config(foreground="green")
	else:
		is_update=True
		strvar.set("■")
		Btn_update.config(foreground="red")






btn1.config(command=changeVar)

btn2.config(command=changeVar1)
btn3.config(command=changeVar3)
btn4.config(command=changeVar4)
btn5.config(command=changeVar5)
btn6.config(command=changeVar6)
btn7.config(command=changeVar7)
Btn_update.config(command=cmd_mod)

master.mainloop()
 
### 直接读写
##sun = pm.read_int(0x1A39E7E0)
##print('阳光值是：' + str(sun))
##print('写入阳光值10000...')
##pm.write_int(0x1A39E7E0, 10000)
##print('当前阳光值是：' + str(pm.read_int(0x1A39E7E0)))
## 
## 
### 使用指针读写
### [1A399280 + 5560] == 0x1A39E7E0
### [02761A10 + 768] == 1A399280
### [006A9EC0] == 02761A10
## 
##base = 0x006A9EC0
##ptr1 = pm.read_int(base)  # [base] == 02761A10
##print(ptr1)
##ptr2 = pm.read_int(ptr1 + 0x768)  # [02761A10 + 768] == 1A399280
##print(ptr2)
##sun = pm.read_int(
##    ptr2 + 0x5560
##)  # [1A399280 + 5560] == 0x1A39E7E0, 读取0x1A39E7E0内的值 即阳光值
##print('使用指针读取到的阳光值是：' + str(sun))
